﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using CommonCodeManagers.Model;
using CommonCodeManagers.plugin;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace CommonCodeManagers
{
    public partial class WindowForm : Form
    {
        public WindowForm()
        {
            InitializeComponent();
        }

        private Timer timer = null;

        private void WindowForm_Load(object sender, EventArgs e)
        {
            LoadMethod();
        }

        public void LoadMethod()
        {
            if (string.IsNullOrEmpty(_gitConfig))
            {
                btnSetGit.Visible = true;
            }

            GetContentByGit();
            //GetContentByUrl();
            if (timer==null)
            {
                timer = new Timer
                {
                    Interval = 5 * 60 * 1000
                };
                timer.Tick += new EventHandler(CommitContentByGit);
                //timer.Tick += new EventHandler(PostContentToUrl);
                timer.Start();
            }            
            
            LoadTreeViewType();
        }

        #region 从Git远程获取内容        

        private static readonly string _codeFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "gitPath");

        private static readonly string _codeJsonFilePath = Path.Combine(_codeFilePath, "code.json");
        private string _gitConfig => AppConfig.GetConfig("GitAccount");
        private string _jsonAccount => string.IsNullOrEmpty(_gitConfig)?"":DESEncrypt.Decrypt(_gitConfig);  

        private void GetContentByGit()
        {
            
            if (!Directory.Exists(_codeFilePath))
            {
                //Directory.CreateDirectory(_codeFilePath);
                //不存在则，克隆仓库
                GitHandler.CloneRepository(_jsonAccount, _codeFilePath);
            }
            else
            {
                //存在则从仓库拉取
                GitHandler.PullText(_jsonAccount, _codeFilePath);
            }

            //默认内容
            string content = "{\"allTypes\": [],\"data\": []}";
            if (!File.Exists(_codeJsonFilePath))
            {
                FileOperate.WriteFile(_codeJsonFilePath, content);
            }

        }

        private void CommitContentByGit(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(_gitConfig)) return;

            try
            {
                GitHandler.PushText(_jsonAccount, _codeFilePath);
            }
            catch (Exception exception)
            {
                timer.Stop();
            }
            
        }

        #endregion

        #region 从自己的云服务器获取内容

        private void GetContentByUrl()
        {
            string content = HttpHandler.Get("http://118.25.1.114/Text/GetText?name=zkqinfo");
            FileOperate.WriteFile(AppDomain.CurrentDomain.BaseDirectory + "/code.json", content);
        }

        private void PostContentToUrl(object sender, EventArgs e)
        {
            try
            {
                string jsonStr = FileOperate.ReadFile(AppDomain.CurrentDomain.BaseDirectory + "/code.json");
                Dictionary<string, string> dicts =
                    new Dictionary<string, string> { { "name", "zkqinfo" }, { "content", jsonStr } };
                HttpHandler.Post("http://118.25.1.114/Text/SetText", dicts);
            }
            catch (Exception exception)
            {
                timer.Stop();
                MessageBox.Show(exception.Message);
                throw;
            }

        }


        #endregion

        private void typeTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Parent == null)
            {
                comboBoxCodeType.Text = e.Node.Text;
                txtName.Text = string.Empty;
                txtCode.Text = string.Empty;
                return;
            }

            comboBoxCodeType.Text = "";

            comboBoxCodeType.Text = e.Node.Parent.Text;
            txtName.Text = e.Node.Text;

            txtCode.Text = e.Node.Tag.ToString();
            isEditChange = false;
        }

        private void Change_Click(object sender, EventArgs e)
        {
            AlterCodeContent();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            MessageBoxButtons mess = MessageBoxButtons.OKCancel;

            DialogResult dr = MessageBox.Show("确定要删除代码吗？", "提示", mess);
            if (dr != DialogResult.OK) return;

            string jsonStr = FileOperate.ReadFile(_codeJsonFilePath);//FileOperate.ReadFile(AppDomain.CurrentDomain.BaseDirectory + "/code.json");

            JObject json = JObject.Parse(jsonStr);

            var parentData = json["data"].Children().FirstOrDefault(a => a["type"].ToString() == comboBoxCodeType.Text);
            if (parentData == null)
            {
                MessageBox.Show(comboBoxCodeType.Text + "类别不存在！");
                return;
            }

            var node = parentData["childs"].Children().FirstOrDefault(a => a["name"].ToString() == txtName.Text);

            if (string.IsNullOrEmpty(txtName.Text) && string.IsNullOrEmpty(txtCode.Text))
            {
                parentData.Remove();
                json["allTypes"].FirstOrDefault(a => a.ToString() == comboBoxCodeType.Text)?.Remove();
            }
            else if(node!=null)
            {
                node.Remove();
            }
            else
            {
                MessageBox.Show(txtName.Text + "名称的代码不存在！");
                return;
            }

            comboBoxCodeType.Text = "";
            txtCode.Text = "";
            txtName.Text = "";

            FileOperate.WriteFile(_codeJsonFilePath, json.ToString());//FileOperate.WriteFile(AppDomain.CurrentDomain.BaseDirectory + "/code.json", json.ToString());

            LoadTreeViewType();
        }

        private bool isEditChange = false;
        private void txtCode_TextChanged(object sender, EventArgs e)
        {
            if (isEditChange)
            {
                AlterCodeContent();
            }
            
            isEditChange= true;
        }

        #region 方法

        private void AlterCodeContent()
        {
            if (string.IsNullOrEmpty(txtName.Text)) return;
            
            string jsonStr = FileOperate.ReadFile(_codeJsonFilePath);//FileOperate.ReadFile(AppDomain.CurrentDomain.BaseDirectory + "/code.json");

            JObject json = JObject.Parse(jsonStr);

            var parentData = json["data"].Children().FirstOrDefault(a => a["type"].ToString() == comboBoxCodeType.Text) ??
                             new JObject(new JProperty("type", comboBoxCodeType.Text), new JProperty("childs", new JArray()));


            var node = parentData["childs"].Children().FirstOrDefault(a => a["name"].ToString() == txtName.Text);

            if (node != null)
            {
                node["codeContent"] = txtCode.Text;
            }
            else
            {
                node = new JObject(new JProperty("name", txtName.Text), new JProperty("codeContent", txtCode.Text));

                (parentData["childs"] as JArray)?.Add(node);

                if (!json["allTypes"].Any(a => a.ToString() == comboBoxCodeType.Text))
                {
                    (json["allTypes"] as JArray)?.Add(comboBoxCodeType.Text);

                    (json["data"] as JArray)?.Add(parentData);
                }
            }

            FileOperate.WriteFile(_codeJsonFilePath, json.ToString()); //FileOperate.WriteFile(AppDomain.CurrentDomain.BaseDirectory + "/code.json", json.ToString());

            LoadTreeViewType();
        }


        private void LoadTreeViewType()
        {
            typeTree.Nodes.Clear();
            comboBoxCodeType.Items.Clear();

            string jsonStr = FileOperate.ReadFile(_codeJsonFilePath);//FileOperate.ReadFile(AppDomain.CurrentDomain.BaseDirectory + "/code.json");

            JObject json = JObject.Parse(jsonStr);
            var types = json.SelectToken("allTypes");
            foreach (var type in JArray.Parse(types.ToString()))
            {
                comboBoxCodeType.Items.Add(type.ToString());
                var node = new TreeNode(type.ToString());

                var childs = from j in json["data"].Children()
                    where j["type"].ToString() == type.ToString()
                    select j["childs"];
                foreach (var child in childs.Children())
                {
                    var childNode = new TreeNode(child["name"].ToString())
                    {
                        Tag = child["codeContent"].ToString()
                    };
                    node.Nodes.Add(childNode);
                }

                node.Expand();
                typeTree.Nodes.Add(node);
            }
        }
        #endregion

        private void txtName_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            BuildCode bc = new BuildCode()
            {
                TemplateContent = txtCode.Text
            };
            bc.ShowDialog();
        }

        private void typeTree_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            CommitContentByGit(sender,e);
            //PostContentToUrl(sender, e);
            MessageBox.Show("提交成功！");
        }

        private void btnSetGit_Click(object sender, EventArgs e)
        {
            SetGitAccount setGit = new SetGitAccount();
            setGit.ShowDialog();
        }

        private void typeTree_AfterSelect(object sender, TreeViewEventArgs e)
        {

        }
    }
}
